 /*
 * @description: 视频上传
 * @Author: along
 * @Date: 2021-03-16
 * @Last Modified by: along
 * @Last Modified time: 2021-03-16
 */

<template>
    <div class="videoUpload">
        <el-dialog
            title="上传视频"
            :visible.sync="dialogVisible"
            width="614px"
            :close-on-click-modal="false"
            :close-on-press-escape="false"
            :before-close="done"
        >
            <div class="header">
                <div class="header-wrap">
                    <el-upload
                        class="upload-demo"
                        action="https://jsonplaceholder.typicode.com/posts/"
                        accept="video/*"
                        :multiple="true"
                        :limit="limit"
                        :file-list="fileList"
                        :show-file-list="false"
                        :http-request="fnUploadFile"
                        :on-change="fnChangeUpload"
                        :before-upload="beforeUploadVideo"
                        :on-exceed="beforeUploadExcwwd"
                    >
                        <el-button
                            size="small"
                            type="primary"
                            plain
                            :style="{width: '520px'}"
                            :disabled="limit === 1"
                        >
                            继续上传视频
                        </el-button>
                    </el-upload>
                </div>
            </div>
            <div class="wrap">
                <div
                    v-for="(option,i) in uploadList"
                    :key="i"
                    class="wrap-list"
                >
                    <div
                        v-if="option"
                        class="wrap-content"
                    >
                        <el-progress
                            :class="option.process == 100 ? 'wrap-progress' : 'wrap-progress none-success'"
                            type="circle"
                            color="#44D984"
                            :stroke-width="7"
                            :percentage="option.process"
                            :status="option.status"
                        />
                        <p class="name"> {{ option.name }} </p>
                        <p
                            :style="{fontSize: '12px', cursor: 'pointer', color: '#409EFF', whiteSpace: 'nowrap'}"
                            v-if="option.status == 'exception'"
                            @click="nextVideo(option.name,i)"
                        >
                            重新上传
                        </p>
                    </div>
                    <div
                        class="wrap-waring"
                        v-if="option.status == 'exception' && option.text"
                    >
                        {{ option.text }}
                    </div>
                </div>
            </div>

            <!-- 底部按钮 -->
            <div class="foot">
                <el-button
                    size="medium"
                    type="default"
                    :style="{width: '120px', marginRight: '32px'}"
                    @click="handleCancelUpload()"
                >
                    取消
                </el-button>
                <el-button
                    size="medium"
                    type="primary"
                    :style="{width: '120px'}"
                    @click="handleCompleteTask()"
                    :disabled="video_complite"
                >
                    完成
                </el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
export default {
    name: 'VideoUpload',
    props: {
        limit: {
            type: Number,
            default: 10
        }
    },
    data () {
        return {
            dialogVisible: false,//组件开关
            keyword_school: '',//学校搜索字段
            uploadingFile: false,
            uploadList: [],
            fileList: [],//记录上传视频总列表
            uploadIndex: 0,//记录当前上传视频位置
            uploadInfo: [],//存储每次上传视频的信息
            type: '',//打开弹窗类型,add:上传 edit:更新
            resultList: [],//记录已上传的视频，未关闭弹窗
            errorList: [],//记录视频上传失败列表
            uploadVideoLength: 0,//记录视频上传数量，是否完全上传成功
            falg: true
        };
    },
    watch: {
        dialogVisible (val) {
            if(val) {
                this.uploadList = [];
                this.fileList = [];
                this.uploadIndex = 0;
                this.resultList = [];
                this.uploadingFile = false;
                this.uploadVideoLength = 0;
                this.errorList = [];
            }
        }
    },
    computed: {
        video_complite () {
            let flag = false;

            for(let key=0; key<this.uploadList.length; key++){
                if(this.uploadList[key].process < 100) {
                    flag = true;
                    break;
                }
            }

            return flag;
        }
    },
    filters: {},
    mounted () {},
    methods: {
        /**
         * @description 显示弹窗
         */
        show () {
            this.dialogVisible = true;
        },

        /**
         * @description 关闭弹窗
         */
        hide () {
            this.dialogVisible = false;

            // 关闭弹窗时清空之前数据
            this.$emit('clear');
        },

        /**
         * @description 上传视频操作
         */
        showUpload (video) {
            setTimeout(() => {
                this.fileList = video.fileList;
                this.fnUploadFile(video.event);
            },500);
        },

        /**
         * @description 关闭操作
         */
        done (done) {
            setTimeout(() => {
                if(this.video_complite) {
                    this.$confirm('关闭后正在上传的视频将不会保存,是否继续?', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(() => {
                        window.location.reload();
                        this.hide();
                    });
                } else {
                    this.hide();
                }
            },100);
        },

        /**
         * @description 取消上传视频
         */
        handleCancelUpload () {
            setTimeout(() => {
                if(this.video_complite) {
                    this.$confirm('关闭后正在上传的视频将不会保存,是否继续?', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(() => {
                        window.location.reload();
                        this.hide();
                    });
                } else {
                    this.hide();
                }
            },100);
        },

        /**
         * @description 完成上传视频
         */
        handleCompleteTask () {
            if(!this.video_complite) {
                this.hide();
            }
        },

        /**
         * @description 获取视频上传地址
         */
        fnGetUploadAuth(file, callback) {
            this.$post('/stuhire_room_series/SeriesVideo/uploadAuth', {
                file_name: file.name,
                file_size: file.size
            }, resp => {
                if (resp.code == 1) {
                    callback(resp.data);
                }else{
                    this.$message({
                        type: 'warning',
                        message: resp.msg,
                        center: true
                    });
                }
            });
        },

        /**
         * @description 获取视频信息，处理上传
         */
        fnUploadFile(event) {
            // console.log('event', event, this.fileList);

            this.uploadInfo = [];
            this.uploadingFile = true;
            this.uploadVideoLength = 0;

            this.fnGetUploadAuth(event.file, (data) => {
                let fd = new FormData();

                fd.append('policy', data.body.policy);
                fd.append('signature', data.body.signature);
                fd.append('file', event.file);

                // 加载上传数据
                this.uploadInfo.push({
                    data: data,
                    fd: fd,
                    index: this.uploadIndex,
                    name: event.file.name
                });
                this.uploadIndex++;//生成视频序列

                //处理同步并行上传
                if(Number(this.uploadInfo.length) + Number(this.uploadList.length) == this.fileList.length) {
                    for(let key=0; key<this.uploadInfo.length; key++){
                        this.uploadList.push({
                            name: this.uploadInfo[key].name,
                            process: 0,
                            status: 'success',
                            text: '',
                            result: 'loading',
                            school_id: this.uploadInfo[key].school_id
                        });
                        this.uploadVideo(this.uploadInfo[key]['data'], this.uploadInfo[key]['fd'], this.uploadInfo[key]['index'],this.uploadInfo[key]['name']);
                    }
                }
            });
        },

        /**
         * @description 视频上传函数
         */
        uploadVideo (data, fd, index, name) {
            this.$upload({
                url: data.api,
                data: fd,
                progress: (e) => {
                    setTimeout(()=>{
                        this.uploadList[index]['process'] = Number(e.percent.toFixed(1) * 1);
                    },10);
                    // console.log('当前上传位置:' + index, '当前上传进度:' + Number(e.percent.toFixed(1) * 1));
                },
                success: resp => {
                    if (resp.code == 200) {
                        // console.log('当前上传成功视频:' + index, '上传成功数据:' + JSON.stringify(resp.url));
                        this.$set(this.uploadList[index], 'status', 'success');
                        this.$set(this.uploadList[index], 'result', 'success');
                        this.$set(this.uploadList[index], 'video_size', resp.file_size);
                        this.$set(this.uploadList[index], 'video_path', resp.url);
                        this.$set(this.uploadList[index], 'text', '');
                        this.$set(this.uploadList[index], 'video_ext', resp.mimetype.split('/')[1]);

                        const uploadFlag = this.uploadList.reduce((cur,next) => {
                            cur.push(next.result);
                            return cur;
                        },[]);

                        // console.log('uploadList', this.uploadList, uploadFlag.indexOf('success'));

                        let list = this.uploadList.filter(item => name.includes(item.name));//当前上传数据

                        if(uploadFlag.indexOf('success') > -1) {
                            this.uploadVideoLength++;

                            this.$emit('success', list);

                            if(this.uploadVideoLength == this.uploadInfo.length) {
                                console.log('全部上传完成');
                                this.uploadingFile = false;//打开视频上传按钮开关
                            }
                        }
                    } else {
                        //上传失败
                        this.$notify({
                            title: '提示',
                            message: resp.message,
                            type: 'warning',
                            duration: 2000
                        });
                    }
                },
                fail: error => {
                    console.log(data, fd, index, name, '--fail--');
                    this.$set(this.uploadList[index], 'status', 'exception');
                    this.$set(this.uploadList[index], 'result', 'exception');
                    this.$set(this.uploadList[index], 'text', error.message);
                    this.uploadVideoLength++;
                    this.errorList.push({ //记录当前批次失败失败列表，上传结束后重新上传
                        data: data,
                        fd: fd,
                        index: index,
                        name: name
                    });
                    if(this.uploadVideoLength == this.uploadInfo.length) {
                        console.log('全部上传完成');
                        this.uploadingFile = false;//打开视频上传按钮开关
                    }
                    this.$message({
                        type: error,
                        dangerouslyUseHTMLString: true,
                        message: `<p>视频上传失败,请检测视频格式是否正确,视频是否可以正常播放</p><p>视频名称:${name}</p>`,
                        duration: 5000,
                        showClose: true
                    });
                    // this.uploadVideo(data, fd, index, name);
                }
            });
        },

        /**
         * @description 文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
         */
        fnChangeUpload (file, fileList) {
            this.fileList = fileList;
            // console.log('on-change', file, fileList);
        },

        /**
         * @description 上传文件之前的钩子，参数为上传的文件，若返回 false 或者返回 Promise 且被 reject，则停止上传。
         */
        beforeUploadVideo (file) {
            // console.log('before-upload', file);
            // const isLt80M = file.size / 1024 / 1024 > 80;

            // if(isLt80M) {
            //     this.$notify({
            //         title: '提示',
            //         message: '视频大小不能超过80M',
            //         type: 'warning',
            //         duration: 2000
            //     });
            //     return false;
            // }
        },

        /**
         * @description 文件超出个数限制时的钩子
         */
        beforeUploadExcwwd (files, fileList) {
            // console.log('on-exceed', files, fileList);
            this.$notify({
                title: '提示',
                message: `最多一次只可以上传${this.limit}个视频`,
                type: 'warning',
                duration: 2000
            });
            return false;
        },

        /**
         * @description 删除视频
         */
        deleteVideo (index) {
            if(this.uploadingFile) {
                this.$notify({
                    title: '提示',
                    message: '请等待批次视频上传完成',
                    type: 'warning',
                    duration: 2000
                });
                return false;
            }
            this.uploadList.splice(index, 1);
            this.fileList.splice(index, 1);
            this.uploadIndex--;//下表减1
            this.resultList = JSON.parse(JSON.stringify(this.uploadList));
        },

        /**
         * @desc 重新上传视频
         */
        nextVideo (name,i) {
            // if(this.uploadingFile) {
            //     this.$notify({
            //         title: '提示',
            //         message: '请等待批次视频上传完成',
            //         type: 'warning',
            //         duration: 2000
            //     });
            //     return false;
            // }

            let list = this.errorList.filter(item => name.includes(item.name));

            this.uploadList.forEach((el,index) => { //改变状态
                if(el.name == name) {
                    let data = this.uploadList[index];

                    this.$set(data, 'status', 'success');
                    this.$set(data, 'process', 0);
                    this.$set(data, 'text', '');
                }
            });

            console.log(list, 'error');

            this.uploadVideo(list[0]['data'], list[0]['fd'], list[0]['index'], list[0]['name']);
        }
    }
};
</script>

<style lang="less" scoped>
.videoUpload {
    display: flex;
    flex-direction: column;
    .header {
        height: 32px;
        display: flex;
        align-items: center;
        margin-bottom: 24px;
        &-box {
            font-size: 14px;
            color: #333;
            white-space: nowrap;
        }
        &-wrap {
            position: relative;
            .upload-demo {
                position: absolute;
                width: 80px;
                height: 32px;
                left: 0;
                top: -17px;
                z-index: 100;
            }
        }
    }
    .wrap {
        width: 520px;
        background: #FBFBFB;
        border: 1px #EEEEEE solid;
        box-sizing: border-box;
        padding: 5px 32px 24px 32px;
        display: flex;
        flex-direction: column;
        max-height: 400px;
        overflow: auto;
        min-height: 40px;
        border-radius: 4px;
        &::-webkit-scrollbar {
            width: 3px;
        }
        .wrap_none_desc {
            width: 100%;
            height: 70px;
            text-align: center;
            line-height: 93px;
            font-size: 14px;
            color: rgba(153, 153, 153, 1);
        }
        .wrap-list {
            display: flex;
            flex-direction: column;
            .wrap-content {
                height: 46px;
                display: flex;
                align-items: center;
                box-sizing: border-box;
                border-bottom: 1px #EEEEEE solid;
                .name {
                    width: 388px;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                    margin: 0 24px 0 10px;
                    color: #333;
                }
                .el-icon-close {
                    color: rgba(157,157,157,1);
                    font-size: 18px;
                    cursor: pointer;
                    &:hover {
                        color: #409EFF;
                    }
                }
            }
            .wrap-waring {
                color: #EE4E59;
                font-size: 12px;
                margin-top: 8px;
                margin-bottom: 16px;
                margin-left: 28px;
            }
        }
    }
    .foot {
        width: 100%;
        height: 36px;
        display: flex;
        justify-content: center;
        align-items: center;
        margin-top: 32px;
    }
}
</style>

<style lang="less">
.videoUpload {
    .el-dialog__header {
        padding-top: 10px;
        box-shadow:0px 1px 0px 0px rgba(233,233,233,1);
        display: flex;
        align-items: center;
        background: #FAFAFA;
        border-radius: 4px 4px 0 0;
        .el-dialog__title {
            font-weight: 500;
            color: #333;
            font-size: 14px;
        }
        .el-icon-close:before {
            color: rgb(194,194,194);
            font-size: 17px;
            font-weight: bold;
        }
        .el-dialog__headerbtn {
            top: 14px;
        }
    }
    .el-dialog__body {
        padding-left: 60px;
        padding-right: 60px;
    }
    .el-progress-circle {
        width: 18px !important;
        height: 18px !important;
    }
    .none-success .el-progress__text {
        display: none !important;
    }
    .is-exception .el-icon-close {
        font-size: 12px;
        font-weight: bold;
        position: relative;
        top: -2px;
    }
    .el-icon-check {
        font-size: 12px;
        font-weight: bold;
        position: relative;
        top: -1px;;
    }
    .el-progress.is-success .el-progress__text {
        color: #44D984;
    }
    .is-plain {
        background: #ffffff;
    }
}
</style>